/*
 * CAN.cpp
 *
 *  Created on: 2021年8月22日
 *      Author: bingshan
 */


#include "CAN.h"

CAN* CAN::instance = nullptr;

CAN::CAN()
{
    struct sockaddr_can addr;
    struct ifreq ifr;
	struct can_frame frame;
    int loopback = 0; // 0 表示关闭, 1 表示开启(默认)
    socketCan_handler = socket(PF_CAN, SOCK_RAW, CAN_RAW); //创建套接字
    if(socketCan_handler < 0) {
        cerr << "ERROR opening socket" << endl;
        cerr.flush();
        exit(-1);
    }
    strcpy(ifr.ifr_name, "can0" );
    ioctl(socketCan_handler, SIOCGIFINDEX, &ifr); //指定 can0 设备
    addr.can_family = AF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;
	bind(socketCan_handler, (struct sockaddr *)&addr, sizeof(addr)); //将套接字与 can0 绑定
    setsockopt(socketCan_handler, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback));

    SetFilter(10);
    master_thread = new thread(&CAN::_master_exec, this);
    master_thread->detach();
}

void CAN::SetFilter(int val) {
    struct can_filter *rfilter = new struct can_filter[val+1];
    for(int i=0;i<=val;++i) {
        rfilter[i].can_id = i;
        rfilter[i].can_mask = CAN_SFF_MASK;
    }
    setsockopt(socketCan_handler, SOL_CAN_RAW, CAN_RAW_FILTER,   &rfilter,  sizeof(rfilter));
    delete[] rfilter;
}

void CAN::SetFilter(vector<int> &vals) {
    int n = vals.size();
    struct can_filter *rfilter = new struct can_filter[n];
    for(int i=0;i<n;++i) {
        rfilter[i].can_id = vals[i];
        rfilter[i].can_mask = CAN_SFF_MASK;
    }
    setsockopt(socketCan_handler, SOL_CAN_RAW, CAN_RAW_FILTER,   &rfilter,  sizeof(rfilter));
    delete[] rfilter;
}

int CAN::sendMessage(int id, const vector<unsigned char> &vals) {
    int n = vals.size();
    int begin_tmp = 0;
    int idx = 0;
    int nbytes;
    struct can_frame frame = {0};
    int frame_size = sizeof(frame);
    frame.can_id = id;
    while(idx<n) {
        begin_tmp = idx;
        for(int i=0;i<8;++i) {
            frame.data[i] = vals[idx++];
            if(idx==n)
                break;
        }
        frame.can_dlc = idx - begin_tmp;
        nbytes = write(socketCan_handler, &frame, frame_size);
        if(nbytes != frame_size) {
            return 0;
        }
    }
    return 1;
}

int CAN::getMessage(vector<unsigned char> &vals) {
    int nbytes;
    struct can_frame frame = {0};
    if(!vals.empty())
        vals.clear();
    nbytes = read(socketCan_handler ,&frame,sizeof(frame));
    if(nbytes > 0) {
        for(int i=0;i<frame.can_dlc;++i) {
            vals.emplace_back(frame.data[i]);
        }
    }
    return frame.can_id;
}

CAN::~CAN()
{
    if(instance!=nullptr)
        delete instance;
    close(socketCan_handler);
    if(master_thread!=nullptr)
        delete master_thread;
}

void CAN::_master_exec()
{
    int RX_Id;
    vector<unsigned char> RX_Buf;
    while (1)
    {
        RX_Id = getMessage(RX_Buf);
		if(!RX_Buf.empty()) {
			cout << "Message ID: " << RX_Id << '\t';
			for(int i=0;i<RX_Buf.size();++i) {
				cout << (int)RX_Buf[i] << ' ';
			}
			cout << endl;
		} else {
			cout << "No CAN Message!" << endl;
		}
    }
    
}